#include <iostream>
#include <unistd.h>
#include <stdlib.h>
#include <functional>
#include <vector>
#include <string>
#include <signal.h>
#include <sys/wait.h>

void PrintPending(const sigset_t &pending)
{
    std::cout << "curr pending list [" << getpid()  << "]" ;
    for(int signo = 31; signo > 0; signo--)
    {
        if(sigismember(&pending, signo))
        {
            std::cout << 1 ;
        }
        else
        {
            std::cout << 0 ;
        }
    }
    std::cout << std::endl;
}


void non_handler(int signo)
{
    std::cout << "处理：" << signo << std::endl;
}

int main()
{
    // 忽略 2 号信号的两种方式
    // 方式一：系统调用
    ::signal(2, SIG_IGN); //忽略
    // 方式二：动态捕捉
    //::signal(2, non_handler);

    // 1. 对 2 号信号进行屏蔽
    sigset_t block, oblock;
    sigemptyset(&block);
    sigemptyset(&oblock);

    // 1.1. 添加 2 号信号
    // 我们有没有把 2 号信号的屏蔽，设置进入内核中，只是再用户栈上设置了 block 的位图结构
    // 没有设置到内核中
    sigaddset(&block, 2);

    // 1.2 设置进入内核
    sigprocmask(SIG_SETMASK, &block, &oblock);                         

    int cnt = 0;
    while(true)
    {
        // 2. 如何获取 pending 表
        sigset_t pending;
        sigpending(&pending);

        // 2.1 打印
        PrintPending(pending);
        sleep(3);

        cnt++;
        if(cnt == 3){
            std::cout << "解除对 2 号信号的屏蔽" <<std::endl;
            sigprocmask(SIG_SETMASK, &oblock, nullptr);
        }
    }

    return 0;
}



// void handler(int signo)
// {
//     std::cout << "get a new signal: " << signo << std::endl;
//     exit(1);
// }

// int main()
// {
//     // 信号捕捉
//     // 1. 默认
//     // 2. 忽略
//     // 3. 自定义捕捉
//     //::signal(2, handler);
//     //::signal(2, SIG_IGN); // ignore 忽略: 本身就是一个信号捕捉的方法，动作是忽略
//     ::signal(2, SIG_DFL); // defalut 默认
//     while(true)
//     {
//         pause();
//     }
// }